// utils/ossUpload.js
// 跨端（H5/微信小程序）上传到阿里云 OSS
import http from '@/utils/http'
import config from '@/config'
// #ifdef H5
import OSS from 'ali-oss'
// #endif

function isStsExpired() {
	const exp = uni.getStorageSync('stsTokenExpiration')
	if (!exp) return true
	try {
		return new Date(exp).getTime() < Date.now()
	} catch (e) {
		return true
	}
}

async function ensureSts() {
	try {
		if (!uni.getStorageSync('stsToken') || isStsExpired()) {
			const res = await http.get('/aliyun/config/getSts')
			uni.setStorageSync('stsToken', res.data)
			uni.setStorageSync('stsTokenExpiration', res.data.expiration)
		}
		return uni.getStorageSync('stsToken')
	} catch (error) {
		console.error('获取 STS Token 失败:', error)
		throw new Error(`获取 STS Token 失败: ${error.message}`)
	}
}

function buildObjectKey({ dir, filename, ext }) {
	const safeDir = dir || config.ossConfig.ossDevDepositAddress || ''
	const ts = Date.now()
	const suffix = ext ? (ext.startsWith('.') ? ext : `.${ext}`) : ''
	const base = filename ? filename : `${ts}`
	
	return `${safeDir}${base}${suffix}`
}

/**
 * 上传文件到 OSS（跨端）
 * @param {Object} params
 * @param {String} params.filePath 选择的本地文件路径（uni.chooseImage 返回的 path）
 * @param {String} [params.dir] OSS 目标目录前缀（如：'test/idCard/'）
 * @param {String} [params.objectKey] 完整的 OSS 对象 Key（传入则优先使用）
 * @param {String} [params.filename] 文件名（不含后缀）
 * @param {String} [params.ext] 文件后缀（如：'jpg' 或 '.jpg'）
 * @returns {Promise<{key: string, url: string}>}
 */
export async function uploadToOss({ filePath, dir, objectKey, filename, ext }) {
	
	try {
		if (!filePath) throw new Error('filePath 不能为空')
		
		const sts = await ensureSts()
		let key = objectKey || buildObjectKey({ dir, filename, ext })
		// #ifdef H5
		try {
			console.log(1, 'H5:OSS客户端', key);
			const client = new OSS({
				region: sts.regionId, // 上传后的域名
				accessKeyId: sts.accessKeyId, // 后台的临时签名ID
				accessKeySecret: sts.accessKeySecret, // 后台的临时签名密钥
				stsToken: sts.securityToken,
				bucket: sts.bucketName // OSS仓库名
			})
			const result = await client.multipartUpload(key, filePath)
			const url = (sts.domain ? `${sts.domain}/` : '') + result.name
			return { key: result.name, url }
		} catch (error) {
			console.error('H5 OSS 上传失败:', error)
			throw new Error(`H5 上传失败: ${error.message}`)
		}
		// #endif

		// #ifdef MP-WEIXIN
		try {
			// 小程序环境建议使用表单直传：需要后端提供 policy/signature 等参数
			const policyResp = await http.post('/oss/token', { fileName: key })
			const { host, policy, signature, accessKeyId, securityToken, domain } = policyResp.data || {}
			
			if (!host || !policy || !signature || !accessKeyId) {
				throw new Error('缺少表单直传参数，请后端提供')
			}
			
			await new Promise((resolve, reject) => {
				uni.uploadFile({
					url: host,
					filePath: filePath,
					name: 'file',
					formData: {
						key: key,
						policy: policy,
						signature: signature,
						OSSAccessKeyId: accessKeyId,
						success_action_status: '200',
						...(securityToken ? { 'x-oss-security-token': securityToken } : {})
					},
					success: (res) => {
						if (res.statusCode === 200 || res.statusCode === 204) {
							resolve()
						} else {
							reject(new Error(`OSS 上传失败: ${res.statusCode}`))
						}
					},
					fail: (err) => reject(err)
				})
			})
			
			const url = (domain ? `${domain}/` : (config.imgUrl || '')) + key
			return { key, url }
		} catch (error) {
			console.error('小程序 OSS 上传失败:', error)
			throw new Error(`小程序上传失败: ${error.message}`)
		}
		// #endif
	} catch (error) {
		console.error('uploadToOss 整体错误:', error)
		throw error
	}
}

export default { uploadToOss }


